/*********IIC通信基础工程建设************/
//时间：2021/12/12
//文件名：IIC.c
//作者：吴东桓
//SCL:时钟线  p2^7
//SDA：数据线 P2^6
//应当包含基础文件sys.h

//送起始位 sda=1->0
#include "IIC.H" 
bit  ack;          //应答标志位
void I2C_Start()
{
  SDA=1;
  SCL=1;
  Delay10us();
  SDA=0;
  Delay10us();
  SCL=0; 
}
void I2C_Start_time()
{
  SDA_time=1;
  SCL_time=1;
  Delay10us();
  SDA_time=0;
  Delay10us();
  SCL_time=0; 
}
//送停止位 sda=0->1
void I2C_Stop()
{
  SDA=0;
  SCL=1;
  Delay10us();
  SDA=1;
}
void I2C_Stop_time()
{
  SDA_time=0;
  SCL_time=1;
  Delay10us();
  SDA_time=1;
}
//主机发送ACK(包含ack:sda=0)
void Send_ACK(void)
{  //设置SDA 口为输出
   SDA=0;
   SCL=0;
   Delay10us();
   SCL=1;
   Delay10us();	
   SCL=0;
   SDA=1;
}
void Send_ACK_time(void)
{  //设置SDA 口为输出
   SDA_time=0;
   SCL_time=0;
   Delay10us();
   SCL_time=1;
   Delay10us();	
   SCL_time=0;
   SDA_time=1;
}
//主机发送NACK(no_ack:sda=1）
void Send_NOT_ACK(void)
{  //设置SDA 口为输出
   SDA=1;  
   SCL=0;
   Delay10us();
   SCL=1;
   Delay10us();
   SDA=1;
   SCL=0;
}
void Send_NOT_ACK_time(void)
{  //设置SDA 口为输出
   SDA_time=1;  
   SCL_time=0;
   Delay10us();
   SCL_time=1;
   Delay10us();
   SDA_time=1;
   SCL_time=0;
}
// 检测 SDA是否回ACK（ack:sda=1；Nack:sda=0）
u8 Receive_ACK(void)
{ 
	
	 //设置SDA 口为输入
	u8 ACK_Flag = 0;//应答标志位   1:ACK,0:NACK
	u8 cnt=0;
	SCL=0;
	Delay10us();
   SCL=1;
   Delay10us();
	while((SDA==1)&&cnt<100)//判断
		cnt++;

	if(cnt==100)
	{
		ACK_Flag=0;//n ack
	}else
	{
		ACK_Flag=1;//ack
	}

	SCL=0;
	Delay10us();
	return ACK_Flag;
}
u8 Receive_ACK_time(void)
{ 
	
	 //设置SDA 口为输入
	u8 ACK_Flag = 0;//应答标志位   1:ACK,0:NACK
	u8 cnt=0;
	SCL_time=0;
	Delay10us();
   SCL_time=1;
   Delay10us();
	while((SDA_time==1)&&cnt<100)//判断
		cnt++;

	if(cnt==100)
	{
		ACK_Flag=0;//n ack
	}else
	{
		ACK_Flag=1;//ack
	}

	SCL_time=0;
	Delay10us();
	return ACK_Flag;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Write_IIC_Byte(u8 Byte) //往IIC从机写一个字节
{
	u8 BitCnt;
     for(BitCnt=0;BitCnt<8;BitCnt++)         //要传送的数据长度为8位
    {
         if((Byte<<BitCnt)&0x80)
             SDA=1;                          //判断发送位
        else
           SDA=0;               
           Delay1us();
           SCL=1;                            //置时钟线为高，通知被控器开始接收数据位
          Delay10us();                       //保证时钟高电平周期大于4μs   
           SCL=0;
     }
   
     Delay1us();
     SDA=1;                                  //8位发送完后释放数据线，准备接收应答位
    Delay1us();  
     SCL=1;
     Delay1us();
     if(SDA==1)
         ack=0;   
     else
         ack=1;                              //判断是否接收到应答信号
    SCL=0;
     Delay1us();
}
void Write_IIC_Byte_time(u8 Byte) //往IIC从机写一个字节
{
	u8 BitCnt;
     for(BitCnt=0;BitCnt<8;BitCnt++)         //要传送的数据长度为8位
    {
         if((Byte<<BitCnt)&0x80)
             SDA_time=1;                          //判断发送位
        else
           SDA_time=0;               
           Delay1us();
           SCL_time=1;                            //置时钟线为高，通知被控器开始接收数据位
          Delay10us();                       //保证时钟高电平周期大于4μs   
           SCL_time=0;
     }
   
     Delay1us();
     SDA_time=1;                                  //8位发送完后释放数据线，准备接收应答位
    Delay1us();  
     SCL_time=1;
     Delay1us();
     if(SDA_time==1)
         ack=0;   
     else
         ack=1;                              //判断是否接收到应答信号
    SCL_time=0;
     Delay1us();
}



u8 Read_IIC_Byte(void)//从 从机 读取一个字节
{
	u8 retc;
  u8 BitCnt;
	retc=0;
	SDA=1;                           //置数据线为输入方式
 for(BitCnt=0;BitCnt<8;BitCnt++)
	{
			 Delay1us(); 
			 SCL=0;                      //置时钟线为低，准备接收数据位
			 Delay10us();                 //时钟低电平周期大于4.7μs
		
			 SCL=1;                      //置时钟线为高使数据线上数据有效
			Delay1us();
			 retc=retc<<1;
			 if(SDA==1)
					 retc=retc+1;            //读数据位,接收的数据位放入retc中
			Delay1us();
	}
	SCL=0;
	Delay1us();
	return(retc);
}
u8 Read_IIC_Byte_time(void)//从 从机 读取一个字节
{
	u8 retc;
  u8 BitCnt;
	retc=0;
	SDA_time=1;                           //置数据线为输入方式
 for(BitCnt=0;BitCnt<8;BitCnt++)
	{
			 Delay1us(); 
			 SCL_time=0;                      //置时钟线为低，准备接收数据位
			 Delay10us();                 //时钟低电平周期大于4.7μs
		
			 SCL_time=1;                      //置时钟线为高使数据线上数据有效
			Delay1us();
			 retc=retc<<1;
			 if(SDA_time==1)
					 retc=retc+1;            //读数据位,接收的数据位放入retc中
			Delay1us();
	}
	SCL_time=0;
	Delay1us();
	return(retc);
}